// feishu/feishu_stream.go
package feishu

import (
	"context"
	"fmt"
	"log"
	"strconv"
	"strings"
	"sync"
	"time"

	"v2/config"
	"v2/model"
	"v2/util"

	lark "github.com/larksuite/oapi-sdk-go/v3"
	larkcore "github.com/larksuite/oapi-sdk-go/v3/core"
	"github.com/larksuite/oapi-sdk-go/v3/event/dispatcher"
	"github.com/larksuite/oapi-sdk-go/v3/event/dispatcher/callback"
	larkws "github.com/larksuite/oapi-sdk-go/v3/ws"
)

// FeishuStreamHandler 飞书 Stream 处理器
type FeishuStreamHandler struct {
	WsClient       *larkws.Client // WebSocket 客户端，用于接收事件
	HttpClient     *lark.Client   // HTTP 客户端，用于调用API
	StreamNotifier *FeiShuStreamNotifier
	isRunning      bool
	mu             sync.Mutex
}

var (
	// 单例实例
	instance *FeishuStreamHandler
	once     sync.Once
)

// GetFeishuStreamHandler 获取单例实例
func GetFeishuStreamHandler() *FeishuStreamHandler {
	once.Do(func() {
		// 从配置中获取飞书应用配置
		feishuConfig := config.Global.Notifier.FeiShuStream
		log.Printf("[FeiShu] 加载配置: %+v", feishuConfig)

		// 创建 Stream 通知器
		streamNotifier := NewFeiShuStreamNotifier(
			feishuConfig.AppID,
			feishuConfig.AppSecret,
			feishuConfig.ReceiveIDType,
			feishuConfig.PhoneNumbers,
		)

		// 创建 HTTP 客户端，用于API调用
		httpClient := lark.NewClient(feishuConfig.AppID, feishuConfig.AppSecret)

		// 创建一个临时变量来保存将要创建的实例
		var handler *FeishuStreamHandler

		// 创建事件处理器
		eventHandler := dispatcher.NewEventDispatcher(
			feishuConfig.VerificationToken,
			feishuConfig.EncryptKey,
		).OnP2CardActionTrigger(func(ctx context.Context, event *callback.CardActionTriggerEvent) (*callback.CardActionTriggerResponse, error) {
			return handler.handleCardAction(ctx, event)
		})

		// 创建 WebSocket 客户端，用于接收事件
		wsClient := larkws.NewClient(
			feishuConfig.AppID,
			feishuConfig.AppSecret,
			larkws.WithEventHandler(eventHandler),
			larkws.WithLogLevel(larkcore.LogLevelDebug),
		)

		// 现在可以创建 handler 实例
		handler = &FeishuStreamHandler{
			WsClient:       wsClient,
			HttpClient:     httpClient,
			StreamNotifier: streamNotifier,
			isRunning:      false,
		}

		instance = handler

		// 如果飞书应用已启用，自动启动 Stream 连接
		if feishuConfig.Enable {
			go instance.Start()
		}
	})

	return instance
}

// Start 启动飞书 Stream 连接（非阻塞）
func (h *FeishuStreamHandler) Start() {
	h.mu.Lock()
	defer h.mu.Unlock()

	if h.isRunning {
		log.Println("[FeiShu] Stream 连接已在运行中")
		return
	}

	// 标记为运行中
	h.isRunning = true

	// 从配置中获取飞书应用配置
	feishuConfig := config.Global.Notifier.FeiShuStream

	// 检查是否启用飞书应用
	if !feishuConfig.Enable {
		log.Println("[FeiShu] 飞书应用未启用，跳过 Stream 连接")
		h.isRunning = false
		return
	}

	// 检查必要配置
	if feishuConfig.AppID == "" || feishuConfig.AppSecret == "" {
		log.Println("[FeiShu] 飞书应用配置不完整，缺少 AppID 或 AppSecret，跳过 Stream 连接")
		h.isRunning = false
		return
	}

	// 在后台启动长连接
	go func() {
		for h.isRunning {
			log.Println("[FeiShu] 正在建立 Stream 连接...")
			err := h.WsClient.Start(context.Background())
			if err != nil {
				log.Printf("[FeiShu] Stream 连接失败: %v，5秒后重试", err)
			} else {
				log.Println("[FeiShu] Stream 连接已关闭，5秒后重试")
			}

			// 检查是否应该继续
			h.mu.Lock()
			shouldContinue := h.isRunning
			h.mu.Unlock()

			if shouldContinue {
				time.Sleep(5 * time.Second)
			}
		}
	}()

	log.Println("[FeiShu] Stream 连接已启动（后台运行）")
}

// Stop 停止飞书 Stream 连接
func (h *FeishuStreamHandler) Stop() {
	h.mu.Lock()
	defer h.mu.Unlock()

	if !h.isRunning {
		log.Println("[FeiShu] Stream 连接未运行")
		return
	}

	h.isRunning = false
	log.Println("[FeiShu] Stream 连接已停止")
}

// IsRunning 检查 Stream 连接是否运行中
func (h *FeishuStreamHandler) IsRunning() bool {
	h.mu.Lock()
	defer h.mu.Unlock()
	return h.isRunning
}

// extractTagsFromVariables 从变量中提取标签
func extractTagsFromVariables(variables map[string]interface{}) map[string]string {
	tags := make(map[string]string)

	// 从tags变量中提取标签
	if tagsStr, ok := variables["tags"].(string); ok {
		// 假设格式是 "- `key`: `value`\n- `key2`: `value2`"
		lines := strings.Split(tagsStr, "\n")
		for _, line := range lines {
			if strings.HasPrefix(line, "- `") {
				// 移除前缀和后缀
				line = strings.TrimPrefix(line, "- `")
				line = strings.TrimSuffix(line, "`")

				// 分割key和value
				parts := strings.SplitN(line, "`: `", 2)
				if len(parts) == 2 {
					tags[parts[0]] = parts[1]
				}
			}
		}
	}

	return tags
}

// 屏蔽2个小时
func (h *FeishuStreamHandler) handleMute2h(event *callback.CardActionTriggerEvent) (*callback.CardActionTriggerResponse, error) {
	return h.handleMuteAlert(event, "mute_2h", "屏蔽2小时", config.Global.Nightingale.MuteDuration2h)
}

// handleMute24h 处理屏蔽24小时
func (h *FeishuStreamHandler) handleMute24h(event *callback.CardActionTriggerEvent) (*callback.CardActionTriggerResponse, error) {
	return h.handleMuteAlert(event, "mute_24h", "屏蔽24小时", config.Global.Nightingale.MuteDuration24h)
}

func (h *FeishuStreamHandler) handleMuteAlert(event *callback.CardActionTriggerEvent, muteType, muteName string, durationHours int) (*callback.CardActionTriggerResponse, error) {
	log.Printf("[FeiShu] 卡片按钮点击: %v", event.Event.Action.Value)

	// 1. 从事件中获取告警ID
	alertID, ok := event.Event.Action.Value["alert_id"]
	if !ok {
		log.Printf("[FeiShu] 未找到告警ID，事件内容: %+v", event.Event.Action.Value)
		return &callback.CardActionTriggerResponse{
			Toast: &callback.Toast{
				Type:    "error",
				Content: "告警ID缺失，请联系管理员",
			},
		}, nil
	}

	// 2. 确保alertID是字符串
	alertIDStr, ok := alertID.(string)
	if !ok {
		log.Printf("[FeiShu] 告警ID类型错误: %v", alertID)
		return &callback.CardActionTriggerResponse{
			Toast: &callback.Toast{
				Type:    "error",
				Content: "告警ID格式错误",
			},
		}, nil
	}

	// 3. 从事件中获取告警时间
	var alarmTimeStr string
	alarmTime, ok := event.Event.Action.Value["time"]
	if ok {
		switch v := alarmTime.(type) {
		case string:
			alarmTimeStr = v
		default:
			alarmTimeStr = time.Now().Format("2006-01-02 15:04:05")
		}
	} else {
		log.Printf("[FeiShu] 未找到告警时间")
		alarmTimeStr = time.Now().Format("2006-01-02 15:04:05")
	}

	// 4. 获取操作人信息
	operatorID := event.Event.Operator.OpenID
	// operatorName := event.Event.Operator.UserName
	// if operatorName == "" {
	// 	operatorName = "用户"
	// 	log.Printf("[FeiShu] 操作人用户名为空，使用默认值")
	// }

	log.Printf("[FeiShu] 用户  (%s) 请求 %s 告警 %s", operatorID, muteName, alertIDStr)

	notes := ""
	if event.Event.Action.FormValue != nil {
		log.Printf("[DEBUG] 表单数据: %+v", event.Event.Action.FormValue) // 调试日志
		if n, ok := event.Event.Action.FormValue["Input_h6vcp251sh"]; ok {
			if str, ok := n.(string); ok {
				notes = str
			} else {
				notes = fmt.Sprintf("%v", n)
			}
			log.Printf("[DEBUG] 获取到备注内容: %s", notes)
		} else {
			log.Printf("[PINGBIDEBUG] 未找到备注内容%")
		}

	}
	log.Printf("[FeiShu] 告警备注: %s", notes)

	// 5. 从 Redis 获取原始告警的所有变量
	originalVariables, exists, err := util.GetAlertVariables(alertIDStr)
	if err != nil {
		log.Printf("[FeiShu] 从 Redis 获取原始告警变量失败: %v", err)
		return &callback.CardActionTriggerResponse{
			Toast: &callback.Toast{
				Type:    "error",
				Content: "获取告警信息失败",
			},
		}, err
	} else if !exists {
		log.Printf("[FeiShu] Redis 中未找到告警 %s 的原始变量", alertIDStr)
		return &callback.CardActionTriggerResponse{
			Toast: &callback.Toast{
				Type:    "error",
				Content: "告警信息不存在",
			},
		}, fmt.Errorf("告警信息不存在")
	}

	// 6. 从原始变量中提取关键信息
	// 提取数据源ID
	datasourceIDs := []int{}
	if dsID, ok := originalVariables["datasource_id"]; ok {
		switch v := dsID.(type) {
		case int:
			datasourceIDs = []int{v}
		case float64: // JSON 解析数字时会转换为 float64
			datasourceIDs = []int{int(v)}
		case []interface{}:
			for _, id := range v {
				if intID, ok := id.(int); ok {
					datasourceIDs = append(datasourceIDs, intID)
				} else if floatID, ok := id.(float64); ok {
					datasourceIDs = append(datasourceIDs, int(floatID))
				}
			}
		case string:
			// 如果是以逗号分隔的字符串，解析为整数数组
			idsStr := strings.Split(v, ",")
			for _, idStr := range idsStr {
				idStr = strings.TrimSpace(idStr)
				if id, err := strconv.Atoi(idStr); err == nil {
					datasourceIDs = append(datasourceIDs, id)
				}
			}
		}
	}

	// 如果没有找到数据源ID，尝试使用默认值
	if len(datasourceIDs) == 0 {
		log.Printf("[FeiShu] 未找到数据源ID，尝试使用默认值")
		defaultDSID := 0
		if defaultDSID > 0 {
			datasourceIDs = []int{defaultDSID}
		}
	}

	// 提取分组ID
	groupID := 0
	if gID, ok := originalVariables["group_id"]; ok {
		switch v := gID.(type) {
		case int:
			groupID = v
		case float64:
			groupID = int(v)
		case string:
			if id, err := strconv.Atoi(v); err == nil {
				groupID = id
			}
		}
	}

	// 提取严重级别
	severities := []int{}
	if sev, ok := originalVariables["severity"]; ok {
		switch v := sev.(type) {
		case int:
			severities = []int{v}
		case float64:
			severities = []int{int(v)}
		case []interface{}:
			for _, s := range v {
				if intS, ok := s.(int); ok {
					severities = append(severities, intS)
				} else if floatS, ok := s.(float64); ok {
					severities = append(severities, int(floatS))
				}
			}
		case string:
			// 如果是以逗号分隔的字符串，解析为整数数组
			sevStr := strings.Split(v, ",")
			for _, sStr := range sevStr {
				sStr = strings.TrimSpace(sStr)
				if s, err := strconv.Atoi(sStr); err == nil {
					severities = append(severities, s)
				}
			}
		}
	}

	// 如果没有找到严重级别，尝试使用默认值
	if len(severities) == 0 {
		log.Printf("[FeiShu] 未找到严重级别，尝试使用默认值")
		// 默认严重级别：2（警告）和 3（严重）
		severities = []int{2, 3}
	}

	// 7. 构建屏蔽规则（符合夜莺V8 API）
	now := time.Now()
	btime := now.Unix()
	etime := now.Add(time.Duration(durationHours) * time.Hour).Unix()

	// 提取标签
	tags := extractTagsFromVariables(originalVariables)
	tagConditions := make([]util.TagCondition, 0, len(tags))
	for key, value := range tags {
		tagConditions = append(tagConditions, util.TagCondition{
			Func:  "==",
			Key:   key,
			Value: value,
		})
	}

	// // 添加告警ID作为标签条件
	// tagConditions = append(tagConditions, util.TagCondition{
	// 	Func:  "==",
	// 	Key:   "alert_id",
	// 	Value: alertIDStr,
	// })

	// 创建屏蔽规则 - 修复格式化问题
	note := fmt.Sprintf("%s - %s", muteName)
	cause := fmt.Sprintf("%s - %s (告警时间: %s)", muteName, alarmTimeStr)

	// 确保不会出现%!s(MISSING)
	if strings.Contains(note, "%!") {
		note = fmt.Sprintf("%s - [用户名问题]", muteName)
	}
	if strings.Contains(cause, "%!") {
		cause = fmt.Sprintf("%s - [用户名问题] (告警时间: %s)", muteName, alarmTimeStr)
	}

	log.Printf("[Nightingale] 使用的数据源ID: %v", datasourceIDs)
	log.Printf("[Nightingale] 使用的分组ID: %d", groupID)
	log.Printf("[Nightingale] 使用的严重级别: %v", severities)

	muteRule := util.MuteRule{
		GroupID:       groupID, // 使用提取的分组ID
		Note:          note,
		Severities:    severities,    // 使用提取的严重级别
		DatasourceIDs: datasourceIDs, // 使用提取的数据源ID
		BTime:         int(btime),
		ETime:         int(etime),
		Tags:          tagConditions,
		Cause:         cause,
		MuteTimeType:  0,
	}

	// 8. 调用夜莺V8 API屏蔽告警
	client := util.NewNightingaleV8Client()
	muteResp, err := client.MuteAlert(muteRule)
	if err != nil {
		log.Printf("[FeiShu] 屏蔽告警失败: %v", err)

		// 提供更友好的错误提示
		userMessage := "屏蔽告警失败，请检查配置或联系管理员"
		if strings.Contains(err.Error(), "连接被拒绝") || strings.Contains(err.Error(), "timeout") {
			userMessage = "无法连接到告警系统，请检查网络或系统状态"
		} else if strings.Contains(err.Error(), "401") || strings.Contains(err.Error(), "403") {
			userMessage = "认证失败，请检查用户名和密码配置"
		} else if strings.Contains(err.Error(), "datasource_ids") {
			userMessage = "数据源ID无效，请检查配置"
		}

		return &callback.CardActionTriggerResponse{
			Toast: &callback.Toast{
				Type:    "error",
				Content: userMessage,
			},
		}, err
	}

	// 9. 构建已屏蔽状态变量
	mutedTime := now.Format("2006-01-02 15:04:05")
	endTime := time.Unix(etime, 0).Format("2006-01-02 15:04:05")

	allVariables := make(map[string]interface{})
	for k, v := range originalVariables {
		allVariables[k] = v
	}

	allVariables["muted_time"] = mutedTime
	// allVariables["muted_by"] = operatorName
	allVariables["muted_reason"] = muteName
	allVariables["muted_duration"] = fmt.Sprintf("%d小时", durationHours)
	allVariables["muted_end_time"] = endTime
	allVariables["mute_id"] = muteResp.Data.ID
	allVariables["status"] = "muted"

	// 添加数据源ID和严重级别到变量中，用于卡片显示
	allVariables["datasource_ids"] = datasourceIDs
	allVariables["severities"] = severities
	allVariables["group_id"] = groupID
	allVariables["alarm_time"] = alarmTimeStr
	allVariables["open_id"] = operatorID
	allVariables["complete_time"] = time.Now().Format("2006-01-02 15:04:05")
	allVariables["notes"] = notes
	// 10. 保存更新后的变量到 Redis
	if err := util.SaveAlertVariables(alertIDStr, allVariables); err != nil {
		log.Printf("[FeiShu] 保存已屏蔽状态失败: %v", err)
	}

	// 11. 返回已屏蔽卡片
	return &callback.CardActionTriggerResponse{
		Toast: &callback.Toast{
			Type:    "success",
			Content: fmt.Sprintf("告警已%s", muteName),
		},
		Card: &callback.Card{
			Type: "template",
			Data: &callback.TemplateCard{
				TemplateID:       config.Global.Notifier.FeiShuStream.AlertMutedCardTemplateID,
				TemplateVariable: allVariables,
			},
		},
	}, nil
}

// handleCardAction 处理卡片按钮点击事件
func (h *FeishuStreamHandler) handleCardAction(ctx context.Context, event *callback.CardActionTriggerEvent) (*callback.CardActionTriggerResponse, error) {
	log.Printf("[FeiShu] 卡片按钮点击: %v", event.Event.Action.Value)

	// 从事件中获取操作类型
	action, ok := event.Event.Action.Value["action"]
	if !ok {
		return nil, nil
	}

	// 确保action是字符串
	actionStr, ok := action.(string)
	if !ok {
		log.Printf("[FeiShu] action 字段不是字符串类型: %v", action)
		return nil, nil
	}

	log.Printf("[FeiShu] 识别到操作类型: %s", actionStr)

	// 处理告警认领
	if actionStr == "claim" {
		return h.handleClaimAlert(event)
	}

	// 处理告警屏蔽2个小时
	if actionStr == "silence2" {
		return h.handleMute2h(event)
	}
	if actionStr == "silence24" {
		return h.handleMute24h(event)

	}

	// 处理告警处理完成
	if actionStr == "complete_alarm" {
		return h.handleCompleteAlert(event)
	}

	log.Printf("[FeiShu] 未知的 action 类型: %s", actionStr)
	return nil, nil
}

// handleClaimAlert 处理告警认领
func (h *FeishuStreamHandler) handleClaimAlert(event *callback.CardActionTriggerEvent) (*callback.CardActionTriggerResponse, error) {
	log.Printf("[FeiShu] 卡片按钮点击: %v", event.Event.Action.Value)

	// 1. 从事件中获取告警ID
	alertID, ok := event.Event.Action.Value["alert_id"]
	if !ok {
		log.Printf("[FeiShu] 未找到告警ID，事件内容: %+v", event.Event.Action.Value)
		return &callback.CardActionTriggerResponse{
			Toast: &callback.Toast{
				Type:    "error",
				Content: "告警ID缺失，请联系管理员",
			},
		}, nil
	}

	// 2. 确保alertID是字符串
	alertIDStr, ok := alertID.(string)
	if !ok {
		log.Printf("[FeiShu] 告警ID类型错误: %v", alertID)
		return &callback.CardActionTriggerResponse{
			Toast: &callback.Toast{
				Type:    "error",
				Content: "告警ID格式错误",
			},
		}, nil
	}

	// 3. 从事件中获取告警时间
	alarmTime, ok := event.Event.Action.Value["time"]
	if !ok {
		log.Printf("[FeiShu] 未找到告警时间")
		alarmTime = time.Now().Format("2006-01-02 15:04:05")
	}

	// 4. 确保alarmTime是字符串
	alarmTimeStr, ok := alarmTime.(string)
	if !ok {
		alarmTimeStr = time.Now().Format("2006-01-02 15:04:05")
	}

	// 5. 获取认领人信息
	claimerID := event.Event.Operator.OpenID

	notes := ""
	if event.Event.Action.FormValue != nil {
		log.Printf("[DEBUG] 表单数据: %+v", event.Event.Action.FormValue)
		if n, ok := event.Event.Action.FormValue["Input_h6vcp251sh"]; ok {
			if str, ok := n.(string); ok {
				notes = str
			} else {
				notes = fmt.Sprintf("%v", n)
			}
			log.Printf("[DEBUG] 获取到备注内容: %s", notes)
		} else {
			log.Printf("[DEBUG] 未找到备注字段")
		}
	}

	log.Printf("[FeiShu] 用户  (%s) 认领告警 %s 备注::%s", claimerID, alertIDStr, notes)
	// 6. 从 Redis 获取原始告警的所有变量
	originalVariables, exists, err := util.GetAlertVariables(alertIDStr)
	if err != nil {
		log.Printf("[FeiShu] 从 Redis 获取原始告警变量失败: %v", err)
		// 如果 Redis 出错，尝试从事件中获取部分信息
		originalVariables = map[string]interface{}{
			"alert_id":      alertIDStr,
			"time":          alarmTimeStr,
			"rule_name":     "未知规则",
			"alert_level":   "未知级别",
			"trigger_value": "未知值",
			"group_name":    "未知组",
			"tags":          "无标签",
		}
	} else if !exists {
		log.Printf("[FeiShu] Redis 中未找到告警 %s 的原始变量", alertIDStr)
		// 如果 Redis 中没有，尝试从事件中获取部分信息
		originalVariables = map[string]interface{}{
			"alert_id":      alertIDStr,
			"time":          alarmTimeStr,
			"rule_name":     "未知规则",
			"alert_level":   "未知级别",
			"trigger_value": "未知值",
			"group_name":    "未知组",
			"tags":          "无标签",
		}
	}

	// 7. 合并认领信息
	allVariables := make(map[string]interface{})
	for k, v := range originalVariables {
		allVariables[k] = v
	}

	allVariables["alarm_time"] = alarmTimeStr
	allVariables["open_id"] = claimerID
	allVariables["complete_time"] = time.Now().Format("2006-01-02 15:04:05")
	allVariables["notes"] = notes

	// 8. 保存更新后的变量到 Redis
	if err := util.SaveAlertVariables(alertIDStr, allVariables); err != nil {
		log.Printf("[FeiShu] 保存已认领状态失败: %v", err)
		// 不返回错误，继续流程
	}

	// 9. 返回已认领卡片
	return &callback.CardActionTriggerResponse{
		Toast: &callback.Toast{
			Type:    "success",
			Content: "告警已认领",
		},
		Card: &callback.Card{
			Type: "template",
			Data: &callback.TemplateCard{
				TemplateID:       config.Global.Notifier.FeiShuStream.AlertClaimedCardTemplateID,
				TemplateVariable: allVariables,
			},
		},
	}, nil
}

func (h *FeishuStreamHandler) handleCompleteAlert(event *callback.CardActionTriggerEvent) (*callback.CardActionTriggerResponse, error) {
	// 1. 从事件中获取告警ID
	alertID, ok := event.Event.Action.Value["alert_id"]
	if !ok {
		log.Printf("[FeiShu] 未找到告警ID，事件内容: %+v", event.Event.Action.Value)
		return &callback.CardActionTriggerResponse{
			Toast: &callback.Toast{
				Type:    "error",
				Content: "告警ID缺失，请联系管理员",
			},
		}, nil
	}

	// 2. 确保alertID是字符串
	alertIDStr, ok := alertID.(string)
	if !ok {
		log.Printf("[FeiShu] 告警ID类型错误: %v", alertID)
		return &callback.CardActionTriggerResponse{
			Toast: &callback.Toast{
				Type:    "error",
				Content: "告警ID格式错误",
			},
		}, nil
	}
	// 3. 直接从事件上下文中获取 open_message_id
	messageID := event.Event.Context.OpenMessageID
	if messageID == "" {
		log.Printf("[FeiShu] 事件上下文中没有 open_message_id")
		return &callback.CardActionTriggerResponse{
			Toast: &callback.Toast{
				Type:    "error",
				Content: "无法获取消息ID",
			},
		}, nil
	}

	log.Printf("[FeiShu] 从事件上下文中获取到 open_message_id: %s", messageID)

	// 3. 从事件中获取告警时间
	alarmTime, ok := event.Event.Action.Value["time"]
	if !ok {
		log.Printf("[FeiShu] 未找到告警时间")
		alarmTime = time.Now().Format("2006-01-02 15:04:05")
	}

	// 4. 确保alarmTime是字符串
	alarmTimeStr, ok := alarmTime.(string)
	if !ok {
		alarmTimeStr = time.Now().Format("2006-01-02 15:04:05")
	}

	// 5. 获取用户ID
	userID := event.Event.Operator.OpenID

	// 6. 获取用户填写的备注
	notes := ""
	if event.Event.Action.FormValue != nil {
		log.Printf("[DEBUG] 表单数据: %+v", event.Event.Action.FormValue)
		if n, ok := event.Event.Action.FormValue["Input_h6vcp251sh"]; ok {
			if str, ok := n.(string); ok {
				notes = str
			} else {
				notes = fmt.Sprintf("%v", n)
			}
			log.Printf("[DEBUG] 获取到备注内容: %s", notes)
		} else {
			log.Printf("[DEBUG] 未找到备注字段")
		}
	}

	log.Printf("[FeiShu] 用户 %s 处理完成告警 %s: %s", userID, alertIDStr, notes)

	// 7. 从 Redis 获取原始告警的所有变量
	originalVariables, exists, err := util.GetAlertVariables(alertIDStr)
	if err != nil {
		log.Printf("[FeiShu] 从 Redis 获取原始告警变量失败: %v", err)
		// 如果 Redis 出错，尝试从事件中获取部分信息
		originalVariables = map[string]interface{}{
			"alert_id":      alertIDStr,
			"time":          alarmTimeStr,
			"rule_name":     "未知规则",
			"alert_level":   "未知级别",
			"trigger_value": "未知值",
			"group_name":    "未知组",
			"tags":          "无标签",
		}
	} else if !exists {
		log.Printf("[FeiShu] Redis 中未找到告警 %s 的原始变量", alertIDStr)
		// 如果 Redis 中没有，尝试从事件中获取部分信息
		originalVariables = map[string]interface{}{
			"alert_id":      alertIDStr,
			"time":          alarmTimeStr,
			"rule_name":     "未知规则",
			"alert_level":   "未知级别",
			"trigger_value": "未知值",
			"group_name":    "未知组",
			"tags":          "无标签",
		}
	}

	// 8. 合并原始变量和新变量
	allVariables := make(map[string]interface{})

	// 先复制原始变量
	for k, v := range originalVariables {
		allVariables[k] = v
	}

	// 添加或覆盖新变量
	allVariables["alarm_time"] = alarmTimeStr
	allVariables["open_id"] = userID
	allVariables["complete_time"] = time.Now().Format("2006-01-02 15:04:05")
	allVariables["notes"] = notes

	// 9. 直接返回新的卡片内容
	return &callback.CardActionTriggerResponse{
		Toast: &callback.Toast{
			Type:    "success",
			Content: "告警处理成功，卡片已更新",
		},
		Card: &callback.Card{
			Type: "template",
			Data: &callback.TemplateCard{
				TemplateID:       config.Global.Notifier.FeiShuStream.AlertResolvedCardTemplateID,
				TemplateVariable: allVariables,
			},
		},
	}, nil
}

// SendAlert 发送告警卡片
func (h *FeishuStreamHandler) SendAlert(alert model.AlertInfo) error {
	if h.StreamNotifier == nil {
		return fmt.Errorf("Stream 通知器未初始化")
	}

	// 发送告警卡片 - 现在 SendAlertCard 只返回 error
	err := h.StreamNotifier.SendAlertCard(alert)
	if err != nil {
		return err
	}

	// 不再需要保存 message_id，因为我们直接从回调事件中获取 open_message_id
	return nil
}
